package com.maxis;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.apache.commons.lang.StringUtils;

public class MaxisChecksum {
	private static final String CONFIG_FILE = "/maxis.properties";
	private static final java.util.Properties APPCFG = new java.util.Properties();
	private String unreadPGPPath = "";
	private String failPGPPath = "";
	private String resultPGPPath = "";
	private String timeInd = "";
	private SimpleDateFormat sdf1 = new SimpleDateFormat("yyMMdd");
	private SimpleDateFormat sdf2 = new SimpleDateFormat("yyyyMMdd");
	private SimpleDateFormat sdf3 = new SimpleDateFormat("yyyyMMdd HH:mm:ss");

	public static void main(String[] args) {
		InputStream stream = MaxisMPOS.class.getResourceAsStream(CONFIG_FILE);
		try {
			APPCFG.load(stream);
			MaxisChecksum fw = new MaxisChecksum();
			fw.unreadPGPPath = APPCFG.getProperty("unread_pgp_path");
			fw.failPGPPath = APPCFG.getProperty("fail_pgp_path");
			fw.resultPGPPath = APPCFG.getProperty("result_pgp_path");
			fw.timeInd = APPCFG.getProperty("time_indicator");
			fw.startWork();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void startWork() throws FileNotFoundException, IOException, NoSuchAlgorithmException {
		String currentDate = sdf1.format(new Date());
		if (this.checkPGPResponseFileExists("error")) {
			System.out.println("Checksum validation terminated due to PGP-ERROR file detected.");
			return;
		}
		String filePath = this.unreadPGPPath;
		System.out.println("Reading PGP folder " + filePath);
		File rootDir = new File(filePath);
		File[] fileList = rootDir.listFiles();
		if (fileList == null) {
			return;
		}
		boolean hasChecksumFile = false;
		boolean allChecked = true;
		File ebdFile = null;
		for (File aFile : fileList) {
			String fileName = aFile.getName().toLowerCase();
			if (fileName.startsWith("ebd")) {
				ebdFile = aFile;
			}
			if ("checksum.txt".equals(fileName)) {
				hasChecksumFile = true;
				System.out.println("Checksum file found.");
				BufferedReader br = new BufferedReader(new FileReader(aFile));
				String checksumLine;
				while ((checksumLine = br.readLine()) != null) {
					if (StringUtils.isNotBlank(checksumLine)) {
						String[] checksumLineArr = checksumLine.split(" ");
						String md5str = checksumLineArr[0];
						String pgpFileName = checksumLineArr[1];
						File pgpFile = new File(filePath + pgpFileName);
						String md5File = "";
						try {
							md5File = this.genMD5String(pgpFile);
						} catch (Exception e) {
							allChecked = false;
						}
						if (md5File.equals(md5str) == false) {
							System.out.println("MD5 check failed : " + pgpFileName);
							System.out.println("MD5 str : " + md5str);
							System.out.println("MD5 generated : " + md5File);
							allChecked = false;
							break;
						}
					}
				}
				br.close();
			}
		}
		if (!hasChecksumFile) {
			allChecked = false;
		}
		if (allChecked == false) {
			System.out.println("Checksum validation error file to be generated.");
			File newEBDFile = new File(ebdFile.getParent() + "\\err_" + ebdFile.getName());
			boolean b = ebdFile.renameTo(newEBDFile);
			System.out.println("Rename ebd file : " + b);
			this.genPGPResponseFile(currentDate, "0");
		} else {
			this.genPGPResponseFile(currentDate, "1");
		}
	}

	public void genPGPResponseFile(String currentDate, String status) throws IOException {
		File resultFolder = new File(this.resultPGPPath + currentDate + "_" + getTimeStatus());
		if (!resultFolder.exists()) {
			resultFolder.mkdir();
		}
		File statusFile = new File(resultFolder.getAbsolutePath() + "\\ack_" + currentDate + "_" + getTimeStatus() + ".txt");
		statusFile.createNewFile();
		try {
			FileWriter f2 = new FileWriter(statusFile, false);
			f2.write(status);
			f2.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public boolean checkPGPResponseFileExists(String statusFileName) {
		return new File(this.failPGPPath + statusFileName + ".txt").exists();
	}

	public String genMD5String(File file) throws NoSuchAlgorithmException, FileNotFoundException, IOException {
		StringBuffer sb = new StringBuffer();
		MessageDigest md = MessageDigest.getInstance("MD5");
		FileInputStream fis = new FileInputStream(file);
		byte[] dataBytes = new byte[1024];
		int nread = 0;
		while ((nread = fis.read(dataBytes)) != -1) {
			md.update(dataBytes, 0, nread);
		}
		// convert the byte to hex format method 1
		byte[] mdbytes = md.digest();
		for (int i = 0; i < mdbytes.length; i++) {
			sb.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
		}
		fis.close();
		return sb.toString();
	}

	private String getTimeStatus() {
		String res = "";
		Date curTime = new Date();
		String strTimeInd = sdf2.format(curTime) + " " + timeInd;
		try {
			if (curTime.after(sdf3.parse(strTimeInd)) || curTime.equals(sdf3.parse(strTimeInd))) {
				res = "2";
			} else {
				res = "1";
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return res;
	}
}
